/*******************************************************************************
 * Copyright 2010 Maciej Kaniewski mk@firegnom.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.firegnom.rat;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.firegnom.rat.net.HttpPoster;
import com.firegnom.rat.util.Constants;

public abstract class ExceptionActivity extends Activity {
  protected static final int TRACE_DIALOG = 1;
  protected static final int PROGRESS_DIALOG = 2;

  private String ver;
  private String trace;
  private String aVer;
  private String pac;
  private String model;

  private String preview;

  private HttpPoster poster;

  @Override
  protected Dialog onCreateDialog(int id) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    switch (id) {
      case TRACE_DIALOG:
        builder.setMessage(preview).setPositiveButton("Done", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
          }
        });
        return builder.create();
      case PROGRESS_DIALOG:
        return ProgressDialog.show(this, "", "Sending Please wait...", true);
    }
    return null;
  }

  private void buildTrace(Intent i) {
    ver = i.getStringExtra(Constants.APPLICATION_VERSION);
    aVer = i.getStringExtra(Constants.ANDROID_VERSION);
    pac = i.getStringExtra(Constants.APPLICATION_PACKAGE);
    model = i.getStringExtra(Constants.PHONE_MODEL);
    trace = i.getStringExtra(Constants.APPLICATION_STACKTRACE);

    preview = "Application ver: ----ver----\nAndroid ver: ----aVer----\nPackage: ----pac----\nPhone model: ----model----\nDetails: ----details----\nStackTrace:\n----trace----";
    preview = preview.replace("----ver----", ver+"");
    preview = preview.replace("----aVer----", aVer+"");
    preview = preview.replace("----pac----", pac+"");
    preview = preview.replace("----model----", model+"");
    preview = preview.replace("----details----", getMoreDetails()+"");
    preview = preview.replace("----trace----", trace+"");

  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent i = getIntent();
    buildTrace(i);
    poster = new HttpPoster(getUrl());
    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    ll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    TextView tv = new TextView(this);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    int height = dm.heightPixels;
    int width = dm.widthPixels;

    tv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, height - 100));
    String msg = getMessage();
    msg = msg == null ? "We are very sorry but application has crashed unexpectedly.\n\nPlease help us make our application better by sending us stack trace" : msg;
    tv.setTextSize(20);
    tv.setText(msg);
    LinearLayout ll1 = new LinearLayout(this);
    ll1.setOrientation(LinearLayout.HORIZONTAL);
    ll1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    boolean send = isSend();
    int buttonWidth = !send ? width : width / 3;
    if (send) {
      Button b = new Button(this);
      b.setLayoutParams(new LayoutParams(buttonWidth, LayoutParams.FILL_PARENT));
      b.setText("Preview");
      b.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
          showDialog(TRACE_DIALOG);
        }
      });

      ll1.addView(b);
      Button b1 = new Button(this);
      b1.setLayoutParams(new LayoutParams(buttonWidth, LayoutParams.FILL_PARENT));
      b1.setText("Send");
      b1.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
          sendTrace();
        }
      });
      ll1.addView(b1);
    }
    Button b2 = new Button(this);
    b2.setLayoutParams(new LayoutParams(buttonWidth, LayoutParams.FILL_PARENT));
    b2.setText("Exit");
    b2.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        Process.killProcess(Process.myPid());
      }
    });
    ll1.addView(b2);

    ll.addView(tv);
    ll.addView(ll1);
    setContentView(ll);
  }

  private void sendTrace() {
    showDialog(PROGRESS_DIALOG);
    new Thread() {
      public void run() {
        poster.sendStackTrace(getSecurityToken(), ver, pac, model, aVer, trace, getMoreDetails());
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return;
        }
        Process.killProcess(Process.myPid());
      };
    }.start();

  }

  /**
   * 
   * @return
   */
  public abstract boolean isSend();

  /**
   * 
   * @return
   */
  public abstract String getMoreDetails();

  /**
   * 
   * @return
   */
  public abstract String getMessage();

  /**
   * 
   * @return
   */
  public abstract String getUrl();

  /**
   * 
   * @return
   */
  public abstract String getSecurityToken();
}
